/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dataanalysis.main;

import dataanalysis.gui.filechooser.MyFileChooser;
import dataanalysis.ASMODE;
import dataanalysis.CLSMODE;
import dataanalysis.Model;
import dataanalysis.gui.methoddlg.ClsMethodDlg;
import dataanalysis.gui.dataviewer.DataTableView;
import dataanalysis.gui.methoddlg.EvlMethodDlg;
import dataanalysis.gui.filechooser.ModelFileChooser;
import dataanalysis.gui.moreoptiondlg.MoreOptionsDlg;
import dataanalysis.gui.filechooser.MySaveDirChooser;
import dataanalysis.gui.frame.MainFrame;
import dataanalysis.gui.methoddlg.PreMethodDlg;
import dataanalysis.gui.dialog.PredictDlg;
import dataanalysis.gui.dialog.ProcessFlowDlg;
import dataanalysis.gui.ProgressDlg;
import dataanalysis.gui.methoddlg.SchMethodDlg;
import dataanalysis.gui.methoddlg.SemiASMethodDlg;
import dataanalysis.gui.statisticPanel.StatisticPanel;
import dataanalysis.gui.TxtResultPanel;
import dataanalysis.gui.dataviewer.VariableTableView;
import dataanalysis.gui.dialog.AddMethodDlg;
import dataanalysis.gui.filechooser.MethodFileChooser;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.JOptionPane;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.zip.GZIPInputStream;
import javax.swing.filechooser.FileFilter;
import weka.attributeSelection.ASEvaluation;
import weka.attributeSelection.ASSearch;
import weka.attributeSelection.semiAS.SemiAttributeSelector;
import weka.classifiers.Classifier;
import weka.core.Instances;
import weka.core.converters.AbstractFileSaver;
import weka.core.converters.ConverterUtils;
import weka.core.converters.FileSourcedConverter;
import weka.filters.Filter;
import weka.gui.ConverterFileChooser;
import weka.gui.ExtensionFileFilter;

/**
 *
 * @author Administrator
 */
public final class MainView {

    private final MainApp m_manager; //主应用程序
    private final MainFrame m_mainFrame; //主窗口
    private final ConverterFileChooser m_openFileChooser;  //文件选择器
    private final MySaveDirChooser m_saveDirChooser;   //文件夹选择器
    private final ProgressDlg m_progressDlg;  //进度条
    private final ModelFileChooser m_modelFileChooser;  //预测模型选择器
    private final ProcessFlowDlg m_processFlowDlg;  //处理流程对话框
    private final PredictDlg m_predictDlg;  //预测模型对话框
    private final AddMethodDlg m_addMethodDlg;  //添加方法对话框
    private final DataTableView m_dataView;  //数据视图
    private final VariableTableView m_variableView;  //变量视图
    private final TxtResultPanel m_txtResultPanel;  //输出面板
    private final StatisticPanel m_statisticPanel;//统计面板
    private final PreMethodDlg m_preMethodDlg;
    private final EvlMethodDlg m_evlMethodDlg;
    private final SchMethodDlg m_schMethodDlg;
    private final SemiASMethodDlg m_semiASMethodDlg;
    private final ClsMethodDlg m_clsMethodDlg;
    private final MoreOptionsDlg m_moreOptionsDlg;
    private final MethodFileChooser m_methodFileChooser;
    private final MyFileChooser m_fileChooser;

    public MainView(final MainApp manager) throws InterruptedException {
        m_manager = manager;
        //主窗口
        m_mainFrame = new MainFrame("DataAnalysis", this);
        //进度条
        m_progressDlg = new ProgressDlg(m_mainFrame);
        m_progressDlg.setVisible(false);
        //文件选择器
        String path = System.getProperty("user.dir");
        File curFile = new File(path);
        m_openFileChooser = new ConverterFileChooser(curFile);
        m_openFileChooser.setMultiSelectionEnabled(false);

        m_saveDirChooser = new MySaveDirChooser(curFile);
        m_saveDirChooser.setMultiSelectionEnabled(false);

        m_modelFileChooser = new ModelFileChooser(curFile);
        m_methodFileChooser = new MethodFileChooser(curFile);

        m_fileChooser = new MyFileChooser(curFile);
        //方法选择对话框
        m_preMethodDlg = new PreMethodDlg(m_mainFrame, true, this);
        m_preMethodDlg.setVisible(false);

        m_evlMethodDlg = new EvlMethodDlg(m_mainFrame, true, this);
        m_evlMethodDlg.setVisible(false);

        m_schMethodDlg = new SchMethodDlg(m_mainFrame, true, this);
        m_schMethodDlg.setVisible(false);

        m_semiASMethodDlg = new SemiASMethodDlg(m_mainFrame, true, this);
        m_semiASMethodDlg.setVisible(false);

        m_clsMethodDlg = new ClsMethodDlg(m_mainFrame, true, this);
        m_clsMethodDlg.setVisible(false);
        //处理流程对话框
        m_processFlowDlg = new ProcessFlowDlg(m_mainFrame, true, this);
        m_processFlowDlg.setVisible(false);

        m_predictDlg = new PredictDlg(m_mainFrame, true, this);
        m_predictDlg.setVisible(false);

        m_addMethodDlg = new AddMethodDlg(m_mainFrame, true, this);
        m_addMethodDlg.setVisible(false);
        //数据视图
        m_dataView = new DataTableView(100, 100);
        //变量视图
        m_variableView = new VariableTableView(100, 100);
        //输出面板
        m_txtResultPanel = new TxtResultPanel(this);

        m_statisticPanel = new StatisticPanel(this);

        m_moreOptionsDlg = new MoreOptionsDlg(m_mainFrame, true, this);
        m_moreOptionsDlg.setVisible(false);
        //初始化视图
        initView();
    }

    public Instances getLoaderData() throws IOException {
        if (m_openFileChooser == null) {
            return null;
        }
        int retVal = m_openFileChooser.showOpenDialog(m_mainFrame);
        if (retVal != ConverterFileChooser.APPROVE_OPTION) {
            return null;
        }
        if (m_openFileChooser.getLoader() != null) {
            Instances data = m_openFileChooser.getLoader().getDataSet();
            return data;
        }
        return null;
    }

    public void openNewInstances(Instances data) {
        m_dataView.setInstances(data);
        m_variableView.setInstances(data);
        m_statisticPanel.setInstances(data);
        this.setResult(null);
        this.initView();
        m_mainFrame.initDataMenuItem();
        m_predictDlg.updateState();
    }

    public String getLoaderFileName() {
        if (m_openFileChooser == null) {
            return null;
        }
        return m_openFileChooser.getSelectedFile().getAbsolutePath();
    }

    public void showPreDlg() {
        m_preMethodDlg.setVisible(true);
    }

    public void showSemiASDlg() {
        m_semiASMethodDlg.setVisible(true);
    }

    public void showClsDlg() {
        m_clsMethodDlg.setVisible(true);
    }

    public void showEvlDlg() {
        m_evlMethodDlg.setVisible(true);
    }

    public void showSchDlg() {
        m_schMethodDlg.setVisible(true);
    }

    public void showFlowDlg() {
        if (m_processFlowDlg == null) {
            return;
        }
        m_processFlowDlg.setVisible(true);
    }

    public void showMoreOptionsDlg() {
        m_moreOptionsDlg.setVisible(true);
    }

    public void OpenNewDataFile() {
        m_manager.openNewDataFile();
    }

    public void showErrorDlg(Exception ex, String string) {
        JOptionPane.showMessageDialog(m_mainFrame,
                "Problem :" + ex.getMessage(),
                string,
                JOptionPane.ERROR_MESSAGE);
    }

    public void setResult(String str) {
        m_txtResultPanel.setResult(str);
    }

    public void setProcessFlowValue(int a, int b, int c) {
        m_manager.setProcessFlowValue(a, b, c);
    }

    public void runDataProcessThread() {
        m_manager.runDataProcessThread();
    }

    public void showProcessDlg(boolean b) {
        m_progressDlg.setVisible(b);
    }

    public boolean isProgressDlgShow() {
        return m_progressDlg.isVisible();
    }

    public void setFilterValueDoc(Filter filter) {
        m_manager.setFilterValueDoc(filter);
    }

    public void setASEvaluationValueDoc(ASEvaluation evaluator) {
        m_manager.setASEvaluationValueDoc(evaluator);
    }

    public void setASSearchValueDoc(ASSearch searcher) {
        m_manager.setASSearchValueDoc(searcher);
    }

    public void setSemiASValueDoc(SemiAttributeSelector semiASSelector) {
        m_manager.setSemiASValueDoc(semiASSelector);
    }

    public void setClassifierValueDoc(Classifier classifier) {
        m_manager.setClassifierValue(classifier);
    }

    public void setSelectedResult(int index) {
        m_manager.setSelectedResult(index);
    }

    private void initView() {
        openDataView(true);
        openVariableView(true);
        m_mainFrame.setView(m_dataView);
    }

    public void openDataView(boolean b) {
        if (!b) {
            m_mainFrame.closeView(m_dataView);
        } else {
            m_mainFrame.openView("数据视图", m_dataView);
        }
    }

    public void openVariableView(boolean b) {
        if (!b) {
            m_mainFrame.closeView(m_variableView);
        } else {
            m_mainFrame.openView("变量视图", m_variableView);
        }
    }

    public void openResultPanel(boolean b) {
        if (!b) {
            m_mainFrame.closeView(m_txtResultPanel);
        } else {
            m_mainFrame.openView("输出面板", m_txtResultPanel);
        }
    }

    public void showWindow() {
        m_mainFrame.setVisible(true);
    }

    public boolean isShowDataView() {
        return m_mainFrame.hasComponent(m_dataView);
    }

    public boolean isShowVariableView() {
        return m_mainFrame.hasComponent(m_variableView);
    }

    public boolean isShowResultView() {
        return m_mainFrame.hasComponent(m_txtResultPanel);
    }

    public boolean isShowStatisticView() {
        return m_mainFrame.hasComponent(m_statisticPanel);
    }

    public boolean isShowProgrammView() {
        return false;
    }

    public void updateAllCapabilitiesFilter(final Instances data) {
        m_preMethodDlg.updateCapabilitiesFilter(data);
        m_evlMethodDlg.updateCapabilitiesFilter(data);
        m_clsMethodDlg.updateCapabilitiesFilter(data);
        m_semiASMethodDlg.updateCapabilitiesFilter(data);
        m_schMethodDlg.updateCapabilitiesFilter(data);
    }

    public void setCurDataByIndex(int i) {
        m_manager.setCurDataByIndex(i);
    }

    public ASSearch getSchValue() {
        return (ASSearch) m_schMethodDlg.getEditorValue();
    }

    public void setSchValue(Object obj) {
        m_schMethodDlg.setEditorValue(obj);
    }

    public ASEvaluation getEvlValue() {
        return (ASEvaluation) m_evlMethodDlg.getEditorValue();
    }

    public void setEvlValue(Object obj) {
        m_evlMethodDlg.setEditorValue(obj);
    }

    public void setEvlOK() {
        m_evlMethodDlg.setOK();
    }

    public void setEvlCancle() {
        m_evlMethodDlg.setCancle();
    }

    public void setSchOK() {
        m_schMethodDlg.setOK();
    }

    public void setSchCancel() {
        m_schMethodDlg.setCancle();
    }

    public void setDataTableViewByIndex(int i) {
        m_manager.setDataTableViewByIndex(i);
    }

    public void setDataTableViewData(Instances data) {
        m_dataView.setInstances(data);
    }

    public void saveAllFiles() {
        m_manager.saveAllFiles();
    }

    public boolean showSaveAllFilesDlg() {
        m_saveDirChooser.setCapabilitiesFilter(m_preMethodDlg.getCapabilitiesFilter());

        int retVal = m_saveDirChooser.showSaveDialog(m_mainFrame);
        if (retVal != MySaveDirChooser.APPROVE_OPTION) {
            return false;
        }
        return true;
    }

    public String getSavePath() {
        return m_saveDirChooser.getSavePath();
    }

    public String getDirChooserExtention() {
        return ((ExtensionFileFilter) m_saveDirChooser.getFileFilter()).getExtensions()[0];
    }

    public void saveData(String fullName, Instances data) {
        if (data == null) {
            return;
        }
        AbstractFileSaver currentConverter = ConverterUtils.getSaverForExtension(getDirChooserExtention());

        try {
            ((FileSourcedConverter) currentConverter).setFile(new File(fullName));
        } catch (IOException ex) {
            ex.printStackTrace();
            this.showErrorDlg(ex, "Save Data");
        }

        this.saveInstancesToFile(currentConverter, data);
    }

    private void saveInstancesToFile(final AbstractFileSaver saver, final Instances inst) {
        try {
            saver.setInstances(inst);
            saver.writeBatch();
        } catch (IOException ex) {
            ex.printStackTrace();
            this.showErrorDlg(ex, "Save Data");
        }
    }

    public void setSaveAllFilesFolderName(String folderName) {
        m_saveDirChooser.setFolderName(folderName);
    }

    public void setMoreOptions(ASMODE ASMode, int ASFoldNum, int ASSeed, CLSMODE clsMode, int clsFoldNum, double clsSplitPercent, int clsSeed) {
        m_manager.setMoreOptions(ASMode, ASFoldNum, ASSeed, clsMode, clsFoldNum, clsSplitPercent, clsSeed);
    }

    public void addModelAction() {
        int retVal = m_modelFileChooser.showOpenDialog(m_mainFrame);
        if (retVal != ModelFileChooser.APPROVE_OPTION) {
            return;
        }
        File file = m_modelFileChooser.getSelectedFile();
        if (!file.exists()) {
            return;
        }
        try {
            //ObjectInputStream input = new ObjectInputStream(new FileInputStream(file.getPath()));
            InputStream is = new FileInputStream(file);
            if (file.getName().endsWith(".gz")) {
                is = new GZIPInputStream(is);
            }
            ObjectInputStream input = new ObjectInputStream(is);
            Model model = (Model) input.readObject();
            input.close();
            boolean bEnabled = m_manager.checkModelCapabilities(model);
            m_predictDlg.addModel(model, m_modelFileChooser.getSelectedFile().getAbsolutePath(), bEnabled);

        } catch (Exception ex) {
            ex.printStackTrace();
            this.showErrorDlg(ex, "Load Model");
        }
    }

    public void showPredictDlg() {
        m_predictDlg.setVisible(true);
    }

    public void runDataPredictThread(final Model model) {
        m_manager.runDataPredictThread(model);
    }

    public void showStatisticPanel(boolean b) {
        if (!b) {
            m_mainFrame.closeView(m_statisticPanel);
        } else {
            m_mainFrame.openView("统计面板", m_statisticPanel);
        }
    }

    public void showDataSpacePanel() {
        m_statisticPanel.showSpaceMode();
        this.showStatisticPanel(true);
    }

    public void showFrequencyPanel() {
        m_statisticPanel.showFreqMode();
        this.showStatisticPanel(true);
    }

    public void showAddMethodPanel() {
        m_addMethodDlg.setVisible(true);
    }

    public void addMethodAction() {
        int retVal = m_methodFileChooser.showOpenDialog(m_mainFrame);
        if (retVal != ModelFileChooser.APPROVE_OPTION) {
            return;
        }
        File[] files = m_methodFileChooser.getSelectedFiles();
        m_addMethodDlg.addFiles(files);
    }

    public void RebuildPreEditor() {
        m_preMethodDlg.RebuildEditor();
    }

    public void RebuildEvlEditor() {
        m_evlMethodDlg.RebuildEditor();
    }

    public void RebuildSchEditor() {
        m_schMethodDlg.RebuildEditor();
    }

    public void RebuildSemiASEditor() {
        m_semiASMethodDlg.RebuildEditor();
    }

    public void RebuildClsEditor() {
        m_clsMethodDlg.RebuildEditor();
    }

    public void connectDatabase(String URL, String user, String password, String query) {
        m_manager.connectDatabase(URL, user, password, query);
    }

    public boolean checkModelCapabilities(Model model) {
        return m_manager.checkModelCapabilities(model);
    }

    public void exportModel() {
        FileFilter modelFilter = new ExtensionFileFilter(".model", "Model object files (*.model)");
        m_fileChooser.setFileFilter(modelFilter);
        int retVal = m_fileChooser.showSaveDialog(m_mainFrame);
        if (retVal != MyFileChooser.APPROVE_OPTION) {
            return;
        }
        String path=m_fileChooser.getSavePath();
        m_fileChooser.setSelectedFile(new File(path));
        m_manager.exportModel(path);
    }

    public void savePredictTxt() {
        FileFilter txtFilter = new ExtensionFileFilter(".txt", "Model parameter files (*.txt)");
        m_fileChooser.setFileFilter(txtFilter);
        int retVal = m_fileChooser.showSaveDialog(m_mainFrame);
        if (retVal != MyFileChooser.APPROVE_OPTION) {
            return;
        }
        String path=m_fileChooser.getSavePath();
        m_fileChooser.setSelectedFile(new File(path));
        m_manager.saveModelTxt(path);
    }
}
